package ua.org.extjsbuilder.parser.runtime.builder;

import java.io.EOFException;

import ua.org.extjsbuilder.parser.IInstruction;
import ua.org.extjsbuilder.parser.runtime.UnparsedToken;
import ua.org.extjsbuilder.parser.runtime.instructions.Cycle;
import ua.org.extjsbuilder.parser.scanner.CharPattern;

public abstract class CyclesInterpreter extends ConditionsInterpreter {

	CyclesInterpreter(UnparsedToken start) {
		super(start);
	}

	@Override
	boolean next() throws EOFException {
		super.next();
		switch(state){
		case FOR_CYCLE:
			parseFor();
			break;
		case DO_CYCLE:
			parseDo();
			break;
		case WHILE_CYCLE:
			parseWhile();
			break;
		}
		return true;
	}

	private void parseWhile() throws EOFException {
		parseCondition();
		parseMainBlock();
		lastComplete = new Cycle(Cycle.WHILE,
				condition,mainBlock);
		state = LEFT_START;
	}

	private void parseDo() throws EOFException {
		if(pos==(data.length-1)&&is('o')){
			pos++;
		}
		parseMainBlock();
		pos++;
		skipWhiteSpaces();
		if(isKeyword(Cycle.WHILE)){
			pos += Cycle.WHILE.length();
		}
		else {
			err("while expected");
		}
		parseCondition();
		if(pos<data.length&&data[pos]!=';'){
			err("Semicolon expected");
		}
		lastComplete = new Cycle(Cycle.DO,
				condition,mainBlock);
		state = LEFT_START;
	}

	private void parseFor() throws EOFException {
		skipWhiteSpaces();
		if(data[pos]!='('){
			err("Open bracket expected");
		}
		ExpressionsInterpreter declareInterpreter = 
			new ExpressionsInterpreter(token,pos,CharPattern.compile(";"));
		declareInterpreter.pos++;
		declareInterpreter.skipWhiteSpaces();
		declareInterpreter.pos--;
		IInstruction declaration = declareInterpreter.buildExpression();
		declareInterpreter.skipWhiteSpaces();
		setState(declareInterpreter);
		
		if(!is(';'))err("Semicolon expected");
		
		ExpressionsInterpreter conditionInterpreter = 
			new ExpressionsInterpreter(token,pos,CharPattern.compile(";"));
		conditionInterpreter.pos++;
		conditionInterpreter.skipWhiteSpaces();
		conditionInterpreter.pos--;
		condition = conditionInterpreter.buildExpression();
		conditionInterpreter.skipWhiteSpaces();
		setState(conditionInterpreter);
		
		if(!is(';'))err("Semicolon expected");
		
		ExpressionsInterpreter incrementInterpreter =
			new ExpressionsInterpreter(token,pos,CharPattern.compile(")"));
		incrementInterpreter.pos++;
		incrementInterpreter.skipWhiteSpaces();
		incrementInterpreter.pos--;
		IInstruction increment = incrementInterpreter.buildExpression();
		incrementInterpreter.skipWhiteSpaces();
		setState(incrementInterpreter);
		
		if(is(')'))nextChar();
		else err("Closing bracket expected");
		
		parseMainBlock();
		
		lastComplete = new Cycle(Cycle.FOR,	declaration, 
				condition, increment, mainBlock);
		state = LEFT_START;
	}
}